home *** CD-ROM | disk | FTP | other *** search
- ;* STRING.ASM
- ;************************************************************************
- ;* *
- ;* PC Scheme/Geneva 4.00 Borland TASM code *
- ;* *
- ;* (c) 1985-1988 by Texas Instruments, Inc. See COPYRIGHT.TXT *
- ;* (c) 1992 by L. Bartholdi & M. Vuilleumier, University of Geneva *
- ;* *
- ;*----------------------------------------------------------------------*
- ;* *
- ;* String & Char operations (interpreter support) *
- ;* *
- ;*----------------------------------------------------------------------*
- ;* *
- ;* Created by: John Jensen Date: 1985 *
- ;* Revision history: *
- ;* - 18 Jun 92: Renaissance (Borland Compilers, ...) *
- ;* - 23 Aug 92: Added accented char up-dowcase support (lb) *
- ;* *
- ;* ``In nomine omnipotentii dei'' *
- ;************************************************************************
- IDEAL
- %PAGESIZE 60, 132
- MODEL small
- LOCALS @@
-
- INCLUDE "scheme.ash"
- INCLUDE "interprt.ash"
-
- DATASEG
- ; Case tables (for characters between 40h and 0bfh)
-
- LABEL locases BYTE
- CHAR = 0
- REPT 100h
- IF (CHAR GE 'A') AND (CHAR LE 'Z')
- DB CHAR+'a'-'A'
- ELSEIF CHAR EQ 128 ; \c{C}
- DB 135
- ELSEIF CHAR EQ 142 ; \"A
- DB 132
- ELSEIF CHAR EQ 143 ; \o{A}
- DB 134
- ELSEIF CHAR EQ 144 ; \'E
- DB 130
- ELSEIF CHAR EQ 146 ; \AE
- DB 145
- ELSEIF CHAR EQ 153 ; \"O
- DB 148
- ELSEIF CHAR EQ 154 ; \"U
- DB 129
- ELSEIF CHAR EQ 165 ; \~N
- DB 164
- ELSE
- DB CHAR
- ENDIF
- CHAR = CHAR+1
- ENDM
-
- LABEL hicases BYTE
- CHAR = 0
- REPT 100h
- IF (CHAR GE 'a') AND (CHAR LE 'z')
- DB CHAR+'A'-'a'
- ELSEIF CHAR EQ 129 ; \"u
- DB 154
- ELSEIF CHAR EQ 130 ; \'e
- DB 144
- ELSEIF CHAR EQ 132 ; \"a
- DB 142
- ELSEIF CHAR EQ 134 ; \o{a}
- DB 143
- ELSEIF CHAR EQ 135 ; \c{c}
- DB 128
- ELSEIF CHAR EQ 145 ; \ae
- DB 146
- ELSEIF CHAR EQ 148 ; \"o
- DB 153
- ELSEIF CHAR EQ 164 ; \~n
- DB 165
- ELSE
- DB CHAR
- ENDIF
- CHAR = CHAR+1
- ENDM
-
- CODESEG
- ;************************************************************************
- ; Char comparisons *
- ;************************************************************************
- MACRO charcmp comparison, case
- LOCAL @@satisfied
- get2op
- xor bx, bx
- mov bl, al
- lea di, [regs+bx]
- mov bl, ah
- add bx, OFFSET regs
- mov al, [(REG bx).bpage]
- cmp al, SPECCHAR*2 ; are sources a characters?
- jne @@error
- cmp al, [(REG di).bpage]
- jne @@error
- IFIDN <case>, <INSENSITIVE>
- mov al, [BYTE (REG bx).disp]
- lea bx, [locases] ; Fetch lower-case equivalents
- xlat
- mov ah, al
- mov al, [BYTE (REG di).disp]
- xlat
- ELSE
- mov al, [BYTE (REG di).disp]
- mov ah, [BYTE (REG bx).disp]
- ENDIF
- cmp al, ah
- j&comparison @@satisfied
- xor ax, ax ; place 'nil in destination reg
- mov [(REG di).bpage], al
- mov [(REG di).disp], ax
- jmp next
- @@satisfied:
- mov [(REG di).bpage], T_PAGE*2 ; place 't in dest. reg
- mov [(REG di).disp], T_DISP
- jmp next
- ENDM
-
- ;************************************************************************
- ;* al ah *
- ;* (char-= char1 char2) char-= dest, src *
- ;* *
- ;* Purpose: Scheme interpreter support for comparing the equality of *
- ;* character data objects. *
- ;* *
- ;* Description: The tags (page numbers) or the objects are compared *
- ;* for equality. If they are not equal, at least one of *
- ;* the operands is not a character, and an error is *
- ;* signaled. If they are equal, a second check to make *
- ;* sure both are characters is performed. *
- ;* *
- ;* After validating the tag fields, the displacement fields*
- ;* are compared for equality. If they are identical, the *
- ;* characters are equal and 't is returned in the destina- *
- ;* tion register. If not equal, 'nil is returned in the *
- ;* destination register. *
- ;************************************************************************
- PROC ch_eq_p
- charcmp e
- @@error:
- lea ax, [@@msg]
- DATASEG
- @@msg DB "CHAR=?", 0
- CODESEG
- in_ch_eq_p:
- add bx, OFFSET regs ; compute address of source 2
- mov cx, 2
- call set_src_error C, ax, cx, di, bx
- jmp sch_err ; link to Scheme debugger
- ENDP
-
- ;************************************************************************
- ;* al ah *
- ;* (char-equal? char1 char2) char-eq? dest, src *
- ;* *
- ;* Purpose: Scheme interpreter support for comparing the equality of *
- ;* character data objects ignoring case. *
- ;* *
- ;* Description: The tags (page numbers) or the objects are compared *
- ;* for equality. If they are not equal, at least one of *
- ;* the operands is not a character, and an error is *
- ;* signaled. If they are equal, a second check to make *
- ;* sure both are characters is performed. *
- ;* *
- ;* The displacements of both operands are loaded and *
- ;* mapped to uppercase. They are then compared for *
- ;* equality. If equal, 't is returned in the destination *
- ;* registers. Otherwise, 'nil is returned. *
- ;************************************************************************
- PROC ch_eq_ci
- charcmp e, INSENSITIVE
- @@error:
- lea ax, [@@msg]
- DATASEG
- @@msg DB "CHAR-CI=?", 0
- CODESEG
- jmp in_ch_eq_p
- ENDP
-
- ;************************************************************************
- ;* al ah *
- ;* (char-< char1 char2) char-< dest, src *
- ;************************************************************************
- PROC ch_lt_p
- charcmp b, cs, m_ch_lt
- @@error:
- lea ax, [@@msg]
- DATASEG
- @@msg DB "CHAR<?", 0
- CODESEG
- jmp in_ch_eq_p
- ENDP
-
- ;************************************************************************
- ;* al ah *
- ;* (char-less? char1 char2) char-less? dest, src *
- ;************************************************************************
- PROC ch_lt_ci
- charcmp b, INSENSITIVE
- @@error:
- lea ax, [@@msg]
- DATASEG
- @@msg DB "CHAR-CI<?", 0
- CODESEG
- jmp in_ch_eq_p
- ENDP
-
- ;************************************************************************
- ;* Char cases *
- ;************************************************************************
- MACRO ch_case direction
- get1op
- mov di, ax
- add di, OFFSET regs
- cmp [(REG di).bpage], SPECCHAR*2
- jne @@error
- mov al, [BYTE (REG di).disp]
- lea bx, [direction]
- xlat
- mov [BYTE (REG di).disp], al
- jmp next
- ENDM
-
- ;************************************************************************
- ;* al *
- ;* (char-upcase char) char-upcase dest *
- ;* *
- ;* Purpose: Scheme interpreter support for conversion of characters *
- ;* to uppercase *
- ;************************************************************************
- PROC ch_up
- ch_case hicases
- @@error:
- lea ax, [@@msg]
- DATASEG
- @@msg DB "CHAR-UPCASE", 0
- CODESEG
- in_ch_up:
- mov cx, 1
- call set_src_error C, ax, cx, di
- jmp sch_err
- ENDP
-
- ;************************************************************************
- ;* al *
- ;* (char-downcase char) char-downcase dest *
- ;* *
- ;* Purpose: Scheme interpreter support for conversion of characters *
- ;* to lowercase *
- ;************************************************************************
- PROC ch_down
- ch_case locases
- @@error:
- lea ax, [@@msg]
- DATASEG
- @@msg DB "CHAR-DOWNCASE", 0
- CODESEG
- jmp in_ch_up
- ENDP
-
- ;************************************************************************
- ;* al ah *
- ;* (make-string len init) make-string len, init *
- ;************************************************************************
- PROC make_str
- get2op
- save <si>
- xor bx, bx
- mov bl, al
- add bx, OFFSET regs
- cmp [(REG bx).bpage], SPECFIX*2
- jne @@error
- mov cx, [(REG bx).disp]
- or cx, cx
- jl @@error ; if size is negative, error
- mov dx, STRTYPE
- push ax bx ; preserve init-reg, dest-reg
- call alloc_block C, bx, dx, cx
- pop bx ax
- mov di, [(REG bx).disp]
- mov bx, [(REG bx).page]
- ldpage es, bx
- mov bl, ah
- mov al, [regs+bx.bpage]
- cmp al, SPECCHAR*2 ; init value a character?
- je str_fill_load
- cmp al, NIL_PAGE*2 ; use default value? (nil?)
- jne @@error
- mov al, ' '
- jmp str_fill_loaded
- @@error:
- lea bx, [@@msg]
- DATASEG
- @@msg DB "MAKE-STRING", 0
- CODESEG
- jmp src_err
- ENDP make_str
-
- ;************************************************************************
- ;* al ah *
- ;* (string-fill! string char) string-fill! str, char *
- ;************************************************************************
- PROC str_fill
- get2op
- save <si>
- xor bx, bx
- mov bl, al
- mov di, bx
- mov bl, [regs+di.bpage]
- cmp [ptype+bx], STRTYPE
- jne @@error
- ldpage es, bx
- mov di, [regs+di.disp]
- mov bl, ah ; copy initialization value register number
- cmp [regs+bx.page], SPECCHAR*2
- jne @@error
- str_fill_load:
- mov al, [BYTE regs+bx.disp]; load initialization character
- str_fill_loaded:
- mov cx, [(STRDEF es:di).len]
- or cx, cx
- jge @@bigstring
- add cx, OFFSET (TYPE STRDEF).buffer + SIZE POINTER
- @@bigstring:
- sub cx, OFFSET (TYPE STRDEF).buffer
- add di, OFFSET (TYPE STRDEF).buffer
- rep stosb
- jmp next_pc
- @@error:
- lea bx, [@@msg]
- DATASEG
- @@msg DB "FILL-STRING!", 0
- CODESEG
- jmp src_err
- ENDP str_fill
-
- ;************************************************************************
- ;* Macro Support for String ref/set *
- ;************************************************************************
- MACRO strch ref_or_set
- local @@bigstring
- get2op
- xor bx, bx
- mov bl, al ; copy string/dest reg number into di
- lea di, [regs+bx]
- IFIDN <ref_or_set>, <SET>
- get1op
- mov dl, al ; save datum in dl
- ENDIF
- save <si>
- mov bl, [(REG di).bpage]
- cmp [ptype+bx], STRTYPE
- jne @@error
- ldpage es, bx
- mov bl, ah ; copy index register number
- cmp [regs+bx.bpage], SPECFIX*2
- jne @@error
- mov bx, [regs+bx.disp]
- or bx, bx
- jl @@badnumber
- mov si, [(REG di).disp]
- mov cx, [(STRDEF es:si).len]
- or cx, cx
- jge @@bigstring
- add cx, OFFSET (TYPE STRDEF).buffer + SIZE POINTER
- @@bigstring:
- add bx, OFFSET (TYPE STRDEF).buffer
- cmp bx, cx
- jge @@badnumber
- ENDM
-
- ;************************************************************************
- ;* al ah *
- ;* (string-ref string index) string-ref str, index *
- ;************************************************************************
- PROC st_ref
- strch REF
- mov [(REG di).bpage], SPECCHAR*2
- mov bl, [BYTE es:si+bx]
- xor bh, bh
- mov [(REG di).disp], bx
- jmp next_pc
- @@error:
- lea bx, [@@msg]
- DATASEG
- @@msg DB "STRING-REF", 0
- CODESEG
- jmp src_err
- @@badnumber:
- lea bx, [@@msg]
- mov dx, 3 ; STRING-REF is 3 bytes long
- in_st_ref:
- restore <si> ; load location pointer and
- sub si, dx ; back up to start of instruction in error
- call disassemble C, bx, si
- mov cx, 1
- mov dx, STRING_OFFSET_ERROR
- call set_numeric_error C, cx, dx, [tmp_adr]
- restore <si>
- jmp sch_err
- ENDP
-
- ;************************************************************************
- ;* al ah al *
- ;* (string-set! string index char) string-set! str, index, char *
- ;************************************************************************
- PROC st_set
- strch SET
- xor dh, dh
- mov di, dx ; copy source value register number
- cmp [regs+di.bpage], SPECCHAR*2
- jne @@error
- mov al, [BYTE regs+di.disp]
- mov [BYTE es:si+bx], al
- jmp next_pc
- @@error:
- lea bx, [@@msg]
- DATASEG
- @@msg DB "STRING-SET!", 0
- CODESEG
- jmp src_err
- @@badnumber:
- lea bx, [@@msg]
- mov dx, 4 ; STRING-SET! is 4 bytes long
- jmp in_st_ref
- ENDP
-
- END
-